home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 430_01 / m68kdis / inst2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-29  |  23.5 KB  |  1,260 lines

  1. /*
  2.  *                 Author:  Christopher G. Phillips
  3.  *              Copyright (C) 1994 All Rights Reserved
  4.  *
  5.  *                              NOTICE
  6.  *
  7.  * Permission to use, copy, modify, and distribute this software and
  8.  * its documentation for any purpose and without fee is hereby granted
  9.  * provided that the above copyright notice appear in all copies and
  10.  * that both the copyright notice and this permission notice appear in
  11.  * supporting documentation.
  12.  *
  13.  * The author makes no representations about the suitability of this
  14.  * software for any purpose.  This software is provided ``as is''
  15.  * without express or implied warranty.
  16.  */
  17.  
  18. /*
  19.  * Most of the functions that determine whether an instruction is valid
  20.  * and then print it (as necessary) are here.
  21.  */
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include "dis.h"
  27. #include "addr.h"
  28.  
  29. void
  30. bit_dynamic(m68kword inst)
  31. {
  32.     int    destreg = inst & 7;
  33.     int    destmode = (inst >> 3) & 7;
  34.     int    type = (inst >> 6) & 3;
  35.     int    srcreg = (inst >> 9) & 7;
  36.     int    size = (destmode == 0) ? LONGWORD : BYTE;
  37.     char    name[10];
  38.  
  39.     if (type == 0) {
  40.         /* BTST */
  41.         if (!ISDEA(destmode, destreg))
  42.             return;
  43.     } else {
  44.         /* BCHG, BCLR, BSET */
  45.         if (!ISADEA(destmode, destreg))
  46.             return;
  47.     }
  48.  
  49.     sprintf(name, "B%s", bitd[type]);
  50.     if (getea(buf2, destreg, destmode, size))
  51.         return;
  52.     sprintf(buf1, "D%d", srcreg);
  53.     instprint(ops2f(2) | size2f(size), name, buf1, buf2);
  54.  
  55.     valid = 1;
  56. }
  57.  
  58. void
  59. bit_static(m68kword inst)
  60. {
  61.     int    reg = inst & 7;
  62.     int    mode = (inst >> 3) & 7;
  63.     int    type = (inst >> 6) & 3;
  64.     int    size = (ISDATA(mode)) ? LONGWORD : BYTE;
  65.     long    value;
  66.     int    failure;
  67.     char    name[10];
  68.  
  69.     if (type == 0) {
  70.         /* BTST */
  71.         if (!ISDEAlessIMM(mode, reg))
  72.             return;
  73.     } else {
  74.         /* BCHG, BCLR, BSET */
  75.         if (!ISADEA(mode, reg))
  76.             return;
  77.     }
  78.  
  79.     value = getval(/* BYTE */ WORD, &failure);
  80.     if (failure)
  81.         return;
  82.     if (value & 0xff00)
  83.         return;
  84.     if (!ISDATA(mode))
  85.         value %= 8;
  86.  
  87.     sprintf(name, "B%s", bitd[type]);
  88.     if (getea(buf2, reg, mode, size))
  89.         return;
  90.     immsprintf(buf1, value);
  91.     instprint(ops2f(2) | size2f(size) | sharp2f(1), name, buf1, buf2);
  92.  
  93.     valid = 1;
  94. }
  95.  
  96. void
  97. biti_reg(const char *name, int size, const char *reg)
  98. {
  99.     long    value;
  100.     int    failure;
  101.  
  102.     value = getval(size, &failure);
  103.     if (failure)
  104.         return;
  105.     immsprintf(buf1, value);
  106.     instprint(ops2f(2) | size2f(size) | sharp2f(1), name, buf1, reg);
  107.  
  108.     if (size == BYTE && (value & 0xff00))
  109.         return;
  110.  
  111.     valid = 1;
  112. }
  113.  
  114. void
  115. biti_size(const char *name, m68kword inst)
  116. {
  117.     int    reg = inst & 7;
  118.     int    mode = (inst >> 3) & 7;
  119.     int    size = (inst >> 6) & 3;
  120.     long    value;
  121.     int    failure;
  122.  
  123.     if (name[0] == 'C') {
  124.         /* CMPI */
  125.         if (!ISDEAlessIMM(mode, reg))
  126.             return;
  127.     } else {
  128.         /* ADDI, ANDI, EORI, ORI, SUBI */
  129.         if (!ISADEA(mode, reg))
  130.             return;
  131.     }
  132.  
  133.     value = getval(size, &failure);
  134.     if (failure)
  135.         return;
  136.  
  137.     immsprintf(buf1, value);
  138.     if (getea(buf2, reg, mode, size))
  139.         return;
  140.     instprint(ops2f(2) | size2f(size) | sharp2f(1), name, buf1, buf2);
  141.  
  142.     valid = 1;
  143. }
  144.  
  145. void
  146. cmp2_chk2(m68kword inst)
  147. {
  148.     int    srcreg = inst & 7;
  149.     int    srcmode = (inst >> 3) & 7;
  150.     int    size = (inst >> 9) & 3;
  151.     long    value;
  152.     int    failure;
  153.     int    destreg;
  154.  
  155.     if (!ISCEA(srcmode, srcreg))
  156.         return;
  157.  
  158.     value = getval(WORD, &failure);
  159.     if (failure)
  160.         return;
  161.     if (getea(buf1, srcreg, srcmode, size))
  162.         return;
  163.     destreg = (value >> 12) & 7;
  164.     Areg2(buf2, (value & 0x8000) ? 'A' : 'D', destreg);
  165.     instprint(ops2f(2) | size2f(size), (value & 0x0800) ? "CHK2" : "CMP2",
  166.       buf1, buf2);
  167.  
  168.     if (value & 0x07ff)
  169.         return;
  170.  
  171.     valid = 1;
  172. }
  173.  
  174. void
  175. movep(m68kword inst)
  176. {
  177.     int    addrreg = inst & 7;
  178.     int    datareg = (inst >> 9) & 7;
  179.     int    opmode = (inst >> 6) & 7;
  180.     int    size = (opmode & 1) ? LONGWORD : WORD;
  181.     long    value;
  182.     int    failure;
  183.  
  184.     value = getval(WORD, &failure);
  185.     if (failure)
  186.         return;
  187.  
  188.     sprintf(buf1, "D%d", datareg);
  189.     immsprintf(buf2, value);
  190.     sprintf(buf2 + strlen(buf2), "(%2.2s)", Areg(addrreg));
  191.     if (opmode & 2)
  192.         instprint(ops2f(2) | size2f(size) | sharp2f(2), "MOVEP",
  193.           buf1, buf2);
  194.     else
  195.         instprint(ops2f(2) | size2f(size) | sharp2f(1), "MOVEP",
  196.           buf2, buf1);
  197.  
  198.     valid = 1;
  199. }
  200.  
  201. void
  202. cas(m68kword inst)
  203. {
  204.     int    reg = inst & 7;
  205.     int    mode = (inst >> 3) & 7;
  206.     int    size;
  207.     int    comparereg;
  208.     int    updatereg;
  209.     long    value;
  210.     int    failure;
  211.  
  212.     if (!ISAMEA(mode, reg))
  213.         return;
  214.  
  215.     switch ((inst >> 9) & 3) {
  216.     case 1:    size = BYTE;        break;
  217.     case 2:    size = WORD;        break;
  218.     case 3:    size = LONGWORD;    break;
  219.     }
  220.  
  221.     value = getval(WORD, &failure);
  222.     comparereg = value & 7;
  223.     updatereg = (value >> 6) & 7;
  224.     if (failure)
  225.         return;
  226.  
  227.     sprintf(buf1, "D%d", comparereg);
  228.     sprintf(buf2, "D%d", updatereg);
  229.     if (getea(buf3, reg, mode, size))
  230.         return;
  231.     instprint(ops2f(3) | size2f(size), "CAS", buf1, buf2, buf3);
  232.  
  233.     if (value & 0xfe38)
  234.         return;
  235.  
  236.     valid = 1;
  237. }
  238.  
  239. void
  240. cas2(m68kword inst)
  241. {
  242.     int    size = (inst & 0x0200) ? LONGWORD : WORD;
  243.     long    value[2];
  244.     int    failure;
  245.     int    comparereg[2];
  246.     int    updatereg[2];
  247.     int    reg[2];
  248.     int    anotd[2];
  249.     int    i;
  250.  
  251.     for (i = 0; i < 2; i++) {
  252.         value[i] = getval(WORD, &failure);
  253.         if (failure)
  254.             return;
  255.         comparereg[i] = value[i] & 7;
  256.         updatereg[i] = (value[i] >> 6) & 7;
  257.         reg[i] = (value[i] >> 12) & 7;
  258.         anotd[i] = (value[i] & 0x8000) ? 'A' : 'D';
  259.     }
  260.  
  261.     sprintf(buf1, "D%d:D%d", comparereg[0], comparereg[1]);
  262.     sprintf(buf2, "D%d:D%d", updatereg[0], updatereg[1]);
  263.     Areg2(buf3, anotd[0], reg[0]);
  264.     buf3[2] = ':';
  265.     Areg2(&buf3[3], anotd[1], reg[1]);
  266.     instprint(ops2f(3) | size2f(size), "CAS2", buf1, buf2, buf3);
  267.  
  268.     valid = 1;
  269. }
  270.  
  271. void
  272. moves(m68kword inst)
  273. {
  274.     int    srcreg = inst & 7;
  275.     int    srcmode = (inst >> 3) & 7;
  276.     int    size = (inst >> 6) & 3;
  277.     long    value;
  278.     int    failure;
  279.     int    reg;
  280.     int    anotd;
  281.     char    *cp1 = buf1, *cp2 = buf2;
  282.  
  283.     if (!ISAMEA(srcmode, srcreg))
  284.         return;
  285.     value = getval(WORD, &failure);
  286.     if (failure)
  287.         return;
  288.  
  289.     reg = (value >> 12) & 7;
  290.     anotd = (value & 0x8000) ? 'A' : 'D';
  291.     if (getea(buf1, srcreg, srcmode, size))
  292.         return;
  293.     Areg2(buf2, anotd, reg);
  294.     if (value & 0x0800) {
  295.         cp1 = buf2;
  296.         cp2 = buf1;
  297.     }
  298.  
  299.     instprint(ops2f(2) | size2f(size), "MOVES", cp1, cp2);
  300.  
  301.     if (value & 0x07ff)
  302.         return;
  303.  
  304.     valid = 1;
  305. }
  306.  
  307. void
  308. move(m68kword inst, int size)
  309. {
  310.     int    srcreg, destreg;
  311.     int    srcmode, destmode;
  312.  
  313.     srcreg = inst & 7;
  314.     srcmode = (inst >> 3) & 7;
  315.     destmode = (inst >> 6) & 7;
  316.     destreg = (inst >> 9) & 7;
  317.  
  318.     if (ISDIRECT(destmode)) {
  319.         if (size == BYTE)
  320.             return;
  321.     } else if (size == BYTE && ISDIRECT(srcmode)
  322.       || !ISAEA(destmode, destreg))
  323.         return;
  324.  
  325.     if (getea(buf1, srcreg, srcmode, size))
  326.         return;
  327.     if (ISDIRECT(destmode)) {
  328.         sprintf(buf2, "%2.2s", Areg(destreg));
  329.         instprint(ops2f(2) | size2f(size), "MOVEA", buf1, buf2);
  330.     } else {
  331.         if (getea(buf2, destreg, destmode, size))
  332.             return;
  333.         instprint(ops2f(2) | size2f(size), "MOVE", buf1, buf2);
  334.     }
  335.  
  336.     valid = 1;
  337. }
  338.  
  339. void
  340. misc_size(const char *name, m68kword inst)
  341. {
  342.     int    reg = inst & 7;
  343.     int    mode = (inst >> 3) & 7;
  344.     int    size = (inst >> 6) & 3;
  345.  
  346.     if (name[0] == 'T') {
  347.         /* TST */
  348.         if (size == BYTE && !ISDEAlessIMM(mode, reg))
  349.             return;
  350.     } else {
  351.         /* CLR, NEG, NEGX, NOT */
  352.         if (!ISADEA(mode, reg))
  353.             return;
  354.     }
  355.  
  356.     if (getea(buf1, reg, mode, size))
  357.         return;
  358.     instprint(ops2f(1) | size2f(size), name, buf1);
  359.  
  360.     valid = 1;
  361. }
  362.  
  363. void
  364. misc_ea(const char *name, m68kword inst, int size)
  365. {
  366.     int    reg = inst & 7;
  367.     int    mode = (inst >> 3) & 7;
  368.  
  369.     if (name[1] < 'C') {
  370.         /* NBCD, TAS */
  371.         if (!ISADEA(mode, reg))
  372.             return;
  373.     } else {
  374.         /* JMP, JSR, PEA */
  375.         if (!ISCEA(mode, reg))
  376.             return;
  377.     }
  378.     if (getea(buf1, reg, mode, size))
  379.         return;
  380.     instprint(ops2f(1), name, buf1);
  381.  
  382.     valid = 1;
  383. }
  384.  
  385. void
  386. chk(m68kword inst)
  387. {
  388.     int    srcreg = inst & 7;
  389.     int    srcmode = (inst >> 3) & 7;
  390.     int    destreg = (inst >> 9) & 7;
  391.  
  392.     if (!ISDEA(srcmode, srcreg))
  393.         return;
  394.  
  395.     if (getea(buf1, srcreg, srcmode, WORD))
  396.         return;
  397.     sprintf(buf2, "D%d", destreg);
  398.     instprint(ops2f(2), "CHK", buf1, buf2);
  399.  
  400.     valid = 1;
  401. }
  402.  
  403. void
  404. lea(m68kword inst)
  405. {
  406.     int    srcreg = inst & 7;
  407.     int    srcmode = (inst >> 3) & 7;
  408.     int    destreg = (inst >> 9) & 7;
  409.     int    retval;
  410.  
  411.     if (!ISCEA(srcmode, srcreg))
  412.         return;
  413.     retval = getea(buf1, srcreg, srcmode, LONGWORD);
  414.     if (retval)
  415.         return;
  416.     sprintf(buf2, "%2.2s", Areg(destreg));
  417.     instprint(ops2f(2), "LEA", buf1, buf2);
  418.  
  419.     valid = 1;
  420. }
  421.  
  422. void
  423. link(m68kword inst, int size)
  424. {
  425.     int    reg = inst & 7;
  426.     long    value;
  427.     int    failure;
  428.  
  429.     value = getval(size, &failure);
  430.     if (failure)
  431.         return;
  432.     sprintf(buf1, "%2.2s", Areg(reg));
  433.     sprintf(buf2, "%ld", value);
  434.     instprint(ops2f(2) | sharp2f(2), "LINK", buf1, buf2);
  435.  
  436.     valid = 1;
  437. }
  438.  
  439. void
  440. unlk(m68kword inst)
  441. {
  442.     int    reg = inst & 7;
  443.  
  444.     sprintf(buf1, "%2.2s", Areg(reg));
  445.     instprint(ops2f(1), "UNLK", buf1);
  446.  
  447.     valid = 1;
  448. }
  449.  
  450. void
  451. swap(m68kword inst)
  452. {
  453.     int    reg = inst & 7;
  454.  
  455.     sprintf(buf1, "D%d", reg);
  456.     instprint(ops2f(1), "SWAP", buf1);
  457.  
  458.     valid = 1;
  459. }
  460.  
  461. void
  462. bkpt(m68kword inst)
  463. {
  464.     int    vector = inst & 0xf;
  465.  
  466.     sprintf(buf1, "%d", vector);
  467.     instprint(ops2f(1) | sharp2f(1), "BKPT", buf1);
  468.  
  469.     valid = 1;
  470. }
  471.  
  472. void
  473. trap(m68kword inst)
  474. {
  475.     int    vector = inst & 0xf;
  476.  
  477.     sprintf(buf1, "%d", vector);
  478.     instprint(ops2f(1) | sharp2f(1), "TRAP", buf1);
  479.  
  480.     valid = 1;
  481. }
  482.  
  483. void
  484. stop_rtd(const char *name)
  485. {
  486.     int    value;
  487.     int    failure;
  488.  
  489.     value = getval(WORD, &failure);
  490.     if (failure)
  491.         return;
  492.  
  493.     sprintf(buf1, "%ld", value);
  494.     instprint(ops2f(1) | sharp2f(1), name, buf1);
  495.  
  496.     valid = 1;
  497. }
  498.  
  499. void
  500. movec(int tocr)
  501. {
  502.     long    value;
  503.     int    failure;
  504.     int    reg;
  505.     int    anotd;
  506.     int    controlreg;
  507.     char    *cr;
  508.     char    *cp1;
  509.     char    *cp2;
  510.  
  511.     value = getval(WORD, &failure);
  512.     if (failure)
  513.         return;
  514.  
  515.     reg = (value >> 12) & 7;
  516.     anotd = (value & 0x8000) ? 'A' : 'D';
  517.     controlreg = value & 0x0fff;
  518.  
  519.     Areg2(buf1, anotd, reg);
  520.     switch (controlreg) {
  521.     case 0x000:    cr = "SFC";    break;    /* Source Function Code */
  522.     case 0x001:    cr = "DFC";    break;    /* Destination Function Code */
  523.     case 0x002:    cr = "CACR";    break;    /* Cache Control Register */
  524.     case 0x800:    cr = "USP";    break;    /* User Stack Pointer */
  525.     case 0x801:    cr = "VBR";    break;    /* Vector Base Register */
  526.     case 0x802:    cr = "CAAR";    break;    /* Cache Address Register */
  527.     case 0x803:    cr = "MSP";    break;    /* Master Stack Pointer */
  528.     case 0x804:    cr = "ISP";    break;    /* Interrupt Stack Pointer */
  529.     default:
  530.         return;
  531.     }
  532.  
  533.     if (tocr) {
  534.         cp1 = buf1;
  535.         cp2 = cr;
  536.     } else {
  537.         cp1 = cr;
  538.         cp2 = buf1;
  539.     }
  540.  
  541.     instprint(ops2f(2), "MOVEC", cp1, cp2);
  542.  
  543.     valid = 1;
  544. }
  545.  
  546. void
  547. ext(m68kword inst)
  548. {
  549.     int    reg = inst & 3;
  550.     int    opmode = (inst >> 6) & 3;
  551.     int    size = (opmode == 2) ? WORD : LONGWORD;
  552.     char    sext[5];
  553.  
  554.     sprintf(buf1, "D%d", reg);
  555.     strcpy(sext, "EXT");
  556.     if (inst & 0x0100)
  557.         strcat(sext, "B");
  558.     instprint(ops2f(1) | size2f(size), sext, buf1);
  559.  
  560.     valid = 1;
  561. }
  562.  
  563. void
  564. movereg(m68kword inst, const char *regname, int to)
  565. {
  566.     int        reg = inst & 7;
  567.     int        mode = (inst >> 3) & 7;
  568.     const char    *cp1, *cp2;
  569.  
  570.     if (getea(buf1, reg, mode, WORD))
  571.         return;
  572.     if (to) {
  573.         if (!ISDEA(mode, reg))
  574.             return;
  575.         cp1 = buf1;
  576.         cp2 = regname;
  577.     } else {
  578.         if (!ISADEA(mode, reg))
  579.             return;
  580.         cp1 = regname;
  581.         cp2 = buf1;
  582.     }
  583.  
  584.     instprint(ops2f(2) | size2f(WORD), "MOVE", cp1, cp2);
  585.  
  586.     valid = 1;
  587. }
  588.  
  589. void
  590. moveusp(m68kword inst, int to)
  591. {
  592.     int    reg = inst & 7;
  593.     char    *cp1 = buf1, *cp2 = "USP";
  594.  
  595.     sprintf(buf1, "%2.2s", Areg(reg));
  596.     if (!to) {
  597.         cp1 = cp2;
  598.         cp2 = buf1;
  599.     }
  600.  
  601.     instprint(ops2f(2) | size2f(LONGWORD), "MOVE", cp1, cp2);
  602.  
  603.     valid = 1;
  604. }
  605.  
  606. static void
  607. reglist(char *s, unsigned long regmask, int mode)
  608. {
  609.     char    *t = s;
  610.  
  611.     if (mode == 4)
  612.         revbits(®mask, 16);
  613.     s = regbyte(s, regmask & 0xff, "D", 0);
  614.     s = regbyte(s, regmask >> 8, "A", s != t);
  615.     if (s == t)
  616.         strcpy(s, "0");
  617. }
  618.  
  619. void
  620. movem(m68kword inst, int to)
  621. {
  622.     int        reg = inst & 7;
  623.     int        mode = (inst >> 3) & 7;
  624.     int        size = (inst & 0x40) ? LONGWORD : WORD;
  625.     unsigned long    regmask;
  626.     int        failure;
  627.     char        *cp1, *cp2;
  628.  
  629.     regmask = getval(WORD, &failure) & 0xffff;
  630.     if (failure)
  631.         return;
  632.     if (getea(buf1, reg, mode, size))
  633.         return;
  634.     reglist(buf2, regmask, mode);
  635.     if (to) {
  636.         if (!ISCEAplusPOST(mode, reg))
  637.             return;
  638.         cp1 = buf1;
  639.         cp2 = buf2;
  640.     } else {
  641.         if (!ISACEAplusPRE(mode, reg))
  642.             return;
  643.         cp1 = buf2;
  644.         cp2 = buf1;
  645.     }
  646.  
  647.     instprint(ops2f(2) | size2f(size), "MOVEM", cp1, cp2);
  648.  
  649.     valid = 1;
  650. }
  651.  
  652. void
  653. dbcc(m68kword inst)
  654. {
  655.     int        reg = inst & 7;
  656.     int        condition = (inst >> 8) & 0xf;
  657.     long        value;
  658.     int        failure;
  659.     char        sdbcc[5];
  660.     m68kaddr    savedpc;
  661.     short        f = ops2f(2);
  662.  
  663.     sprintf(sdbcc, "DB%s", condition == 1 ? "RA" : cc[condition]);
  664.     sprintf(buf1, "D%d", reg);
  665.     savedpc = pc;
  666.     value = getval(WORD, &failure);
  667.     if (failure)
  668.         return;
  669.  
  670.     if (pass == FIRSTPASS && onepass != INCONSISTENT) {
  671.         required[flags & 3] = value + savedpc;
  672.         flags++;
  673.     } else if (pass == LASTPASS && value + savedpc >= initialpc
  674.       && value + savedpc <= initialpc + maxoffset
  675.       && insts[value + savedpc - initialpc].labelnum)
  676.         sprintf(buf2, "L%d",
  677.           insts[value + savedpc - initialpc].labelnum);
  678.     else /* if (pass == DEBUGPASS
  679.       || value + savedpc > initialpc + maxoffset) */
  680.         /* immsprintf(buf2, value); */
  681.         sprintf(buf2, "%lx", (long)(value + savedpc));
  682.     instprint(f, sdbcc, buf1, buf2);
  683.  
  684.     valid = 1;
  685. }
  686.  
  687. void
  688. trapcc(m68kword inst)
  689. {
  690.     int    mode = inst & 7;
  691.     int    condition = (inst >> 8) & 0xf;
  692.     long    value = 0;
  693.     int    failure;
  694.     int    lflags;
  695.  
  696.     sprintf(buf1, "TRAP%s", cc[condition]);
  697.     switch (mode) {
  698.     case 2:
  699.         value = getval(WORD, &failure);
  700.         if (failure)
  701.             return;
  702.         lflags = ops2f(1) | size2f(WORD) | sharp2f(1);
  703.         break;
  704.     case 3:
  705.         value = getval(LONGWORD, &failure);
  706.         if (failure)
  707.             return;
  708.         lflags = ops2f(1) | size2f(LONGWORD) | sharp2f(1);
  709.         break;
  710.     case 4:
  711.         lflags = ops2f(0);
  712.         break;
  713.     default:
  714.         return;
  715.     }
  716.  
  717.     sprintf(buf2, "%ld", value);
  718.  
  719.     instprint(lflags, buf1, buf2);
  720.  
  721.     valid = 1;
  722. }
  723.  
  724. void
  725. scc(m68kword inst)
  726. {
  727.     int    reg = inst & 7;
  728.     int    mode = (inst >> 3) & 7;
  729.     int    condition = (inst >> 8) & 0xf;
  730.  
  731.     if (!ISADEA(mode, reg))
  732.         return;
  733.     sprintf(buf1, "S%s", cc[condition]);
  734.     if (getea(buf2, reg, mode, BYTE))
  735.         return;
  736.     instprint(ops2f(1) | sharp2f(2), buf1, buf2);
  737.  
  738.     valid = 1;
  739. }
  740.  
  741. void
  742. pack_unpk(const char *name, m68kword inst)
  743. {
  744.     int    reg1 = inst & 7;
  745.     int    reg2 = (inst >> 9) & 7;
  746.     long    value;
  747.     int    failure;
  748.  
  749.     if (inst & 8) {
  750.         sprintf(buf1, "-(%2.2s)", Areg(reg1));
  751.         sprintf(buf2, "-(%2.2s)", Areg(reg2));
  752.     } else {
  753.         sprintf(buf1, "D%d", reg1);
  754.         sprintf(buf2, "D%d", reg2);
  755.     }
  756.  
  757.     value = getval(WORD, &failure);
  758.     if (failure)
  759.         return;
  760.     immsprintf(buf3, value);
  761.     instprint(ops2f(3) | sharp2f(3), name, buf1, buf2, buf3);
  762.  
  763.     valid = 1;
  764. }
  765.  
  766. void
  767. addq_subq(m68kword inst)
  768. {
  769.     int    reg = inst & 7;
  770.     int    mode = (inst >> 3) & 7;
  771.     int    size = (inst >> 6) & 3;
  772.     int    data;
  773.  
  774.     if (!ISAEA(mode, reg) || ISDIRECT(mode) && size == BYTE)
  775.         return;
  776.  
  777.     if ((data = (inst >> 9) & 7) == 0)
  778.         data = 8;
  779.     sprintf(buf1, "%d", data);
  780.     if (getea(buf2, reg, mode, size))
  781.         return;
  782.     instprint(ops2f(2) | size2f(size) | sharp2f(1),
  783.       (inst & 0x0100) ? "SUBQ" : "ADDQ", buf1, buf2);
  784.  
  785.     valid = 1;
  786. }
  787.  
  788. void
  789. op1(const char *name, m68kword inst)
  790. {
  791.     int    datareg = (inst >> 9) & 7;
  792.     int    reg = inst & 7;
  793.     int    mode = (inst >> 3) & 7;
  794.     int    size = (inst >> 6) & 3;
  795.     char    *cp1, *cp2;
  796.  
  797.     if (getea(buf1, reg, mode, size))
  798.         return;
  799.     sprintf(buf2, "D%d", datareg);
  800.     if (inst & 0x0100) {
  801.         if (name[0] == 'E') {
  802.             /* EOR */
  803.             if (!ISADEA(mode, reg))
  804.                 return;
  805.         } else {
  806.             /* ADD, AND, OR, SUB */
  807.             if (!ISAMEA(mode, reg))
  808.                 return;
  809.         }
  810.         cp1 = buf2;
  811.         cp2 = buf1;
  812.     } else {
  813.         if (name[0] == 'O' || name[1] == 'N') {
  814.             /* AND, OR */
  815.             if (!ISDEA(mode, reg))
  816.                 return;
  817.         } else {
  818.             /* ADD, CMP, SUB */
  819.             if (ISDIRECT(mode) && size == BYTE)
  820.                 return;
  821.         }
  822.         cp1 = buf1;
  823.         cp2 = buf2;
  824.     }
  825.     instprint(ops2f(2) | size2f(size), name, cp1, cp2);
  826.  
  827.     valid = 1;
  828. }
  829.  
  830. void
  831. op2(const char *name, m68kword inst)
  832. {
  833.     int    datareg = (inst >> 9) & 7;
  834.     int    reg = inst & 7;
  835.     int    mode = (inst >> 3) & 7;
  836.     char    realname[10];
  837.  
  838.     if (!ISDEA(mode, reg))
  839.         return;
  840.     strcpy(realname, name);
  841.     strcat(realname, ((inst >> 8) & 1) ? "S" : "U");
  842.     if (getea(buf1, reg, mode, WORD))
  843.         return;
  844.     sprintf(buf2, "D%d", datareg);
  845.     instprint(ops2f(2) | size2f(WORD), realname, buf1, buf2);
  846.  
  847.     valid = 1;
  848. }
  849.  
  850. void
  851. op2long(const char *name, m68kword inst)
  852. {
  853.     int    reg = inst & 7;
  854.     int    mode = (inst >> 3) & 7;
  855.     char    realname[10];
  856.     long    value;
  857.     int    failure;
  858.     int    rreg;
  859.     int    qreg;
  860.     int    quadword_dividend;
  861.  
  862.     if (!ISDEA(mode, reg))
  863.         return;
  864.     value = getval(WORD, &failure);
  865.     if (failure)
  866.         return;
  867.     if (value & 0x83f8)
  868.         return;
  869.  
  870.     rreg = value & 7;
  871.     qreg = (value >> 12) & 7;
  872.     quadword_dividend = value & 0x0400;
  873.  
  874.     strcpy(realname, name);
  875.     strcat(realname, (value & 0x0800) ? "S" : "U");
  876.     if (realname[0] == 'D' && rreg != qreg && !quadword_dividend)
  877.         strcat(realname, "L");
  878.     if (rreg == qreg && !quadword_dividend)
  879.         sprintf(buf2, "D%d", qreg);
  880.     else
  881.         sprintf(buf2, "D%d:D%d", rreg, qreg);
  882.  
  883.     if (getea(buf1, reg, mode, LONGWORD))
  884.         return;
  885.     instprint(ops2f(2) | size2f(LONGWORD), realname, buf1, buf2);
  886.  
  887.     valid = 1;
  888. }
  889.  
  890. void
  891. opa(const char *name, m68kword inst)
  892. {
  893.     int    addrreg = (inst >> 9) & 7;
  894.     int    reg = inst & 7;
  895.     int    mode = (inst >> 3) & 7;
  896.     int    size = ((inst >> 8) & 1) ? LONGWORD : WORD;
  897.  
  898.     if (getea(buf1, reg, mode, size))
  899.         return;
  900.     sprintf(buf2, "%2.2s", Areg(addrreg));
  901.     instprint(ops2f(2) | size2f(size), name, buf1, buf2);
  902.  
  903.     valid = 1;
  904. }
  905.  
  906. void
  907. opx(const char *name, m68kword inst, int mode, int printsize)
  908. {
  909.     int    destreg = (inst >> 9) & 7;
  910.     int    srcreg = inst & 7;
  911.     int    size = (inst >> 6) & 3;
  912.     int    lflags = ops2f(2);
  913.  
  914.     if (printsize)
  915.         lflags |= size2f(size);
  916.  
  917.     if (inst & 8) {
  918.         if (getea(buf1, srcreg, mode, size))
  919.             return;
  920.         if (getea(buf2, destreg, mode, size))
  921.             return;
  922.     } else {
  923.         sprintf(buf1, "D%d", srcreg);
  924.         sprintf(buf2, "D%d", destreg);
  925.     }
  926.     instprint(lflags, name, buf1, buf2);
  927.  
  928.     valid = 1;
  929. }
  930.  
  931. void
  932. exg(m68kword inst, char c1, char c2)
  933. {
  934.     int    reg1 = (inst >> 9) & 7;
  935.     int    reg2 = inst & 7;
  936.  
  937.     Areg2(buf1, c1, reg1);
  938.     Areg2(buf2, c2, reg2);
  939.     instprint(ops2f(2), "EXG", buf1, buf2);
  940.  
  941.     valid = 1;
  942. }
  943.  
  944. void
  945. bitfield(m68kword inst)
  946. {
  947.     int    reg = inst & 7;
  948.     int    mode = (inst >> 3) & 7;
  949.     int    type = (inst >> 8) & 3;
  950.     long    value;
  951.     int    failure;
  952.     int    destreg;
  953.     int    offset;
  954.     int    width;
  955.     char    name[10];
  956.     int    n;
  957.  
  958.     value = getval(WORD, &failure);
  959.     if (failure)
  960.         return;
  961.     if (value & 0x8000)
  962.         return;
  963.     if ((type & 1) == 0 && (value & 0xf000))
  964.         return;
  965.     destreg = (value >> 12) & 7;
  966.     offset = (value >> 6) & 0x1f;
  967.     width = value & 0x1f;
  968.     sprintf(name, "BF%s", (type & 1) ? bitf[type] : bitd[type]);
  969.  
  970.     if (!ISDIRECT(mode))
  971.         if (name[2] == 'C' || name[2] == 'I' || name[2] == 'S') {
  972.             /* BFCHG, BFCLR, BFINS, BFSET */
  973.             if (!ISACEA(mode, reg))
  974.                 return;
  975.         } else {
  976.             /* BFEXTS, BFEXTU, BFFFO, BFTST */
  977.             if (!ISCEA(mode, reg))
  978.                 return;
  979.         }
  980.  
  981.     if (getea(buf1, reg, mode, BYTE /* actually unsized */))
  982.         return;
  983.     strcpy(buf3, "{");
  984.     n = 1;
  985.     if (value & 0x0800) {
  986.         if (offset & ~7)
  987.             return;
  988.         n += sprintf(buf3 + n, "D%d", offset & 7);
  989.     } else
  990.         n += sprintf(buf3 + n, "%d", offset);
  991.     if (value & 0x0020) {
  992.         if (width & ~7)
  993.             return;
  994.         n += sprintf(buf3 + n, "D%d", width & 7);
  995.     } else
  996.         n += sprintf(buf3 + n, "%d", width ? width : 32);
  997.     strcat(buf3, "}");
  998.     strcat(buf1, buf3);
  999.     if (type & 1) {
  1000.         sprintf(buf2, "D%d", destreg);
  1001.         instprint(ops2f(2), name, buf1, buf2);
  1002.     } else
  1003.         instprint(ops2f(1), name, buf1);
  1004.  
  1005.     valid = 1;
  1006. }
  1007.  
  1008. void
  1009. getshiftname(char *name, int type, int direction)
  1010. {
  1011.     switch (type) {
  1012.     case 0:    strcpy(name, "AS");    break;
  1013.     case 1:    strcpy(name, "LS");    break;
  1014.     case 2:    strcpy(name, "ROX");    break;
  1015.     case 3:    strcpy(name, "RO");    break;
  1016.     }
  1017.     strcat(name, direction ? "L" : "R");
  1018. }
  1019.  
  1020. void
  1021. shift(m68kword inst)
  1022. {
  1023.     int    reg;
  1024.     int    mode;
  1025.     int    type;
  1026.     int    direction = (inst >> 8) & 1;
  1027.     int    data;
  1028.     int    size;
  1029.     char    name[10];
  1030.  
  1031.     reg = inst & 7;
  1032.     if ((size = ((inst >> 6) & 3)) == 3) {
  1033.         size = WORD;
  1034.         mode = (inst >> 3) & 7;
  1035.  
  1036.         if (inst & 0x0800)
  1037.             return;
  1038.         if (!ISAMEA(mode, reg))
  1039.             return;
  1040.  
  1041.         if (getea(buf1, reg, mode, size))
  1042.             return;
  1043.         type = (inst >> 9) & 3;
  1044.         getshiftname(name, type, direction);
  1045.         instprint(ops2f(1), name, buf1);
  1046.     } else {
  1047.         sprintf(buf2, "D%d", reg);
  1048.         type = (inst >> 3) & 3;
  1049.         if (inst & 0x0020)
  1050.             sprintf(buf1, "D%d", (inst >> 9) & 7);
  1051.         else {
  1052.             if ((data = (inst >> 9) & 7) == 0)
  1053.                 data = 8;
  1054.             sprintf(buf1, "#%d", data);
  1055.         }
  1056.         getshiftname(name, type, direction);
  1057.         instprint(ops2f(2) | size2f(size), name, buf1, buf2);
  1058.     }
  1059.  
  1060.     valid = 1;
  1061. }
  1062.  
  1063. void
  1064. cpsave(const char *prefix, m68kword inst)
  1065. {
  1066.     int    reg = inst & 7;
  1067.     int    mode = (inst >> 3) & 7;
  1068.  
  1069.     if (!ISACEAplusPRE(mode, reg))
  1070.         return;
  1071.     if (getea(buf1, reg, mode, BYTE /* actually unsized */))
  1072.         return;
  1073.     sprintf(buf2, "%sSAVE", prefix);
  1074.     instprint(ops2f(1), buf2, buf1);
  1075.  
  1076.     valid = 1;
  1077. }
  1078.  
  1079. void
  1080. cprestore(const char *prefix, m68kword inst)
  1081. {
  1082.     int    reg = inst & 7;
  1083.     int    mode = (inst >> 3) & 7;
  1084.  
  1085.     if (!ISCEAplusPOST(mode, reg))
  1086.         return;
  1087.     if (getea(buf1, reg, mode, BYTE /* actually unsized */))
  1088.         return;
  1089.     sprintf(buf2, "%sRESTORE", prefix);
  1090.     instprint(ops2f(1), buf2, buf1);
  1091.  
  1092.     valid = 1;
  1093. }
  1094.  
  1095. void
  1096. cpdbcc(struct cp *cpptr, m68kword inst)
  1097. {
  1098.     int        reg = inst & 7;
  1099.     long        value;
  1100.     int        failure;
  1101.     char        sdbcc[6];
  1102.     m68kaddr    savedpc;
  1103.     short        f = ops2f(2);
  1104.     unsigned    condition;
  1105.     char        *condstr;
  1106.  
  1107.     savedpc = pc;
  1108.     condition = getval(WORD, &failure) & 0xffff;
  1109.     if (failure)
  1110.         return;
  1111.     if (condition & 0xffc0)
  1112.         return;
  1113.     if ((condstr = cpptr->cc(condition)) == NULL)
  1114.         return;
  1115.     sprintf(sdbcc, "%sDB%s", cpptr->prefix, condstr);
  1116.     sprintf(buf1, "D%d", reg);
  1117.  
  1118.     value = getval(WORD, &failure);
  1119.     if (failure)
  1120.         return;
  1121.  
  1122.     if (pass == FIRSTPASS && onepass != INCONSISTENT) {
  1123.         required[flags & 3] = value + savedpc;
  1124.         flags++;
  1125.     } else if (pass == LASTPASS && value + savedpc >= initialpc
  1126.       && value + savedpc <= initialpc + maxoffset
  1127.       && insts[value + savedpc - initialpc].labelnum)
  1128.         sprintf(buf2, "L%d",
  1129.           insts[value + savedpc - initialpc].labelnum);
  1130.     else /* if (pass == DEBUGPASS
  1131.       || value + savedpc > initialpc + maxoffset) */
  1132.         /* immsprintf(buf2, value); */
  1133.         sprintf(buf2, "%lx", (long)(value + savedpc));
  1134.     instprint(f, sdbcc, buf1, buf2);
  1135.  
  1136.     valid = 1;
  1137. }
  1138.  
  1139. void
  1140. cpbcc(struct cp *cpptr, m68kword inst)
  1141. {
  1142.     unsigned    condition = inst & 0x003f;
  1143.     long        value;
  1144.     int        failure;
  1145.     char        sbcc[5];
  1146.     m68kaddr    savedpc;
  1147.     int        size = (inst & 0x0040) ? LONGWORD : WORD;
  1148.     char        *condstr;
  1149.  
  1150.     if ((condstr = cpptr->cc(condition)) == NULL)
  1151.         return;
  1152.     sprintf(sbcc, "%sB%s", cpptr->prefix, condstr);
  1153.  
  1154.     savedpc = pc;
  1155.     value = getval(size, &failure);
  1156.     if (failure)
  1157.         return;
  1158.  
  1159.     if (cpptr->prefix[0] == 'F' && cpptr->prefix[1] == '\0'
  1160.       && inst == 0xf280 && value == 0) {
  1161.         instprint(ops2f(0), "FNOP");
  1162.         valid = 1;
  1163.         return;
  1164.     }
  1165.  
  1166.     if (onepass != INCONSISTENT
  1167.       && (value < 0 && -value > savedpc - initialpc
  1168.           || value > 0 && value + savedpc > initialpc + maxoffset
  1169.           || !odd && value & 1))
  1170.                 return;
  1171.  
  1172.     if (pass == FIRSTPASS && onepass != INCONSISTENT) {
  1173.         required[flags & 3] = value + savedpc;
  1174.         flags++;
  1175.     } else if (pass == LASTPASS && value + savedpc >= initialpc
  1176.       && value + savedpc <= initialpc + maxoffset
  1177.       && insts[value + savedpc - initialpc].labelnum)
  1178.         sprintf(buf1, "L%d",
  1179.           insts[value + savedpc - initialpc].labelnum);
  1180.     else /* if (pass == DEBUGPASS
  1181.       || value + savedpc > initialpc + maxoffset) */
  1182.         /* immsprintf(buf1, value); */
  1183.         sprintf(buf1, "%lx", (long)(value + savedpc));
  1184.     instprint(ops2f(1), sbcc, buf1);
  1185.  
  1186.     valid = 1;
  1187. }
  1188.  
  1189. void
  1190. cptrapcc(struct cp *cpptr, m68kword inst)
  1191. {
  1192.     unsigned long    value;
  1193.     int        failure;
  1194.     int        lflags;
  1195.     int        mode = inst & 7;
  1196.     unsigned    condition;
  1197.     char        *condstr;
  1198.  
  1199.     condition = getval(WORD, &failure) & 0xffff;
  1200.     if (failure)
  1201.         return;
  1202.     if (condition & 0xffc0)
  1203.         return;
  1204.     if ((condstr = cpptr->cc(condition)) == NULL)
  1205.         return;
  1206.     sprintf(buf1, "%sTRAP%s", cpptr->prefix, condstr);
  1207.  
  1208.     switch (mode) {
  1209.     case 2:
  1210.         value = getval(WORD, &failure);
  1211.         if (failure)
  1212.             return;
  1213.         lflags = ops2f(1) | size2f(WORD) | sharp2f(1);
  1214.         break;
  1215.     case 3:
  1216.         value = getval(LONGWORD, &failure);
  1217.         if (failure)
  1218.             return;
  1219.         lflags = ops2f(1) | size2f(LONGWORD) | sharp2f(1);
  1220.         break;
  1221.     case 4:
  1222.         lflags = ops2f(0);
  1223.         break;
  1224.     default:
  1225.         return;
  1226.     }
  1227.  
  1228.     sprintf(buf2, "%ld", value);
  1229.  
  1230.     instprint(lflags, buf1, buf2);
  1231.  
  1232.     valid = 1;
  1233. }
  1234.  
  1235. void
  1236. cpscc(struct cp *cpptr, m68kword inst)
  1237. {
  1238.     int        reg = inst & 7;
  1239.     int        mode = (inst >> 3) & 7;
  1240.     int        failure;
  1241.     unsigned    condition;
  1242.     char        *condstr;
  1243.  
  1244.     if (!ISADEA(mode, reg))
  1245.         return;
  1246.     condition = getval(WORD, &failure) & 0xffff;
  1247.     if (failure)
  1248.         return;
  1249.     if ((condstr = cpptr->cc(condition)) == NULL)
  1250.         return;
  1251.  
  1252.     if (getea(buf2, reg, mode, BYTE))
  1253.         return;
  1254.  
  1255.     sprintf(buf1, "%sS%s", cpptr->prefix, condstr);
  1256.     instprint(ops2f(1) | sharp2f(2), buf1, buf2);
  1257.  
  1258.     valid = 1;
  1259. }
  1260.